#include "read_config_message.h"
#include "readwritefile.h"
#include "stringtool.h"
#include <iostream>
#include <algorithm>
#include "print.h"

template <typename... Args>
void print_error(Args &&...args)
{
    chainsaw::print_class_error("read_config_message", std::forward<Args>(args)...);
}

bool chainsaw::ReadConfigMessage::kv::empty()
{
    return key.empty() && value.empty();
}

void chainsaw::ReadConfigMessage::kv::clear()
{
    key.clear();
    value.clear();
}

chainsaw::ReadConfigMessage::ReadConfigMessage(std::string config_file)
{
    bool keep_empty_line = false;
    std::vector<std::string> data = read_file(config_file, keep_empty_line);

    trim(data);
    PRP(data);

    kv buffer;
    for (std::string s : data)
    {
        stringtool tool(s);

        if (tool.startsWith("#"))
        {
            if (tool.size() == 1 || (tool.size() > 1 && tool[1] != ' '))
            {
                print_error("usage: #[space]key");
                return;
            }
            else
            {
                if (!buffer.empty())
                {
                    m_data.push_back(buffer);
                    buffer.clear();
                }
                buffer.key = tool.remove_head(2);
            }
        }
        else
        {
            if (buffer.empty())
            {
                print_error("usage: #[space]key");
                print_error("usage: value");
                return;
            }
            else
            {
                buffer.value.push_back(s);
            }
        }
    }
    if (!buffer.empty())
    {
        m_data.push_back(buffer);
    }
}

std::optional<std::vector<std::string>> chainsaw::ReadConfigMessage::get_value(std::string const &key) const
{
    for (auto const &entry : m_data)
    {
        if (entry.key == key)
            return entry.value;
    }

    return std::nullopt;
}

void chainsaw::ReadConfigMessage::print() const
{
    for (kv t : m_data)
    {
        info_nowrap("[ key ] [", t.key, "]");
        if (!t.value.empty())
        {
            raw_endl();

            for (auto const &s : t.value)
            {
                info("[ val ] ", "    [", s, "]");
            }
        }
        else
        {
            raw_endl();
        }
    }
}
